package znet

import (
	"fmt"
	logging "github.com/sirupsen/logrus"
	"net"
	"webdemo/src/zinx/utils"
	"webdemo/src/zinx/zinterface"
)

// 实现IServer接口 Start() Stop() Server()

type Server struct {
	// 服务器名称
	Name      string
	IpVersion string
	IP        string
	Port      int
	MsgHandle zinterface.IMsgHandle
	ConnMgr   zinterface.IConnManager
	// hook函数
	OnConnStart func(conn zinterface.IConnection)
	OnConnStop  func(conn zinterface.IConnection)
}

func (s *Server) Start() {
	go func() {
		// 开启worker工作池
		s.MsgHandle.StartWorkerPool()

		// 1 获取一个TCP的 Addr
		addr, err := net.ResolveTCPAddr(s.IpVersion, fmt.Sprintf("%s:%d", s.IP, s.Port))
		if err != nil {
			logging.Error("[server][Start] ResolveTCPAddr error is ", err)
			return
		}
		// 监听服务器地址
		listener, err := net.ListenTCP(s.IpVersion, addr)
		if err != nil {
			logging.Error("[server][Start] ListenTCP error is ", err)
			return
		}
		logging.Info("[server][Start] ListenTCP success")
		// 阻塞获取客户端连接
		var cid uint32 = 0

		for true {
			conn, err := listener.AcceptTCP()
			if err != nil {
				logging.Error("[server][Start] listener.AcceptTCP error is ", err)
				continue
			}
			// 最大连接个数判断
			if s.ConnMgr.Len() >= utils.GlobalObj.MaxConn {
				logging.Error("[server][Start]conn too max")

				conn.Close()
				continue
			}

			// 和客户端建立连接,处理业务
			dealConn := NewConnection(s, conn, cid, s.MsgHandle)
			cid++
			// 启动当前链接业务
			go dealConn.Start()
			/* 使用 Connection模块处理
			go func() {
				for true {
					buf := make([]byte, 512)
					readCount, err := conn.Read(buf)
					if err != nil {
						logging.Error("[server][Start] conn.Read error is ", err)
						continue
					}
					logging.Info("[server][Start] conn.Read data is %s", string(buf[:readCount]))
					// 回显
					if _, err := conn.Write(buf[:readCount]); err != nil {
						logging.Error("[server][Start] conn.Write error is ", err)
						continue
					}
				}
			}()*/
		}
	}()

}

func (s *Server) Stop() {
	logging.Info("[server][Stop]...")
	s.ConnMgr.ClearConn()
}

func (s *Server) AddRouter(msgId uint32, router zinterface.IRouter) {
	s.MsgHandle.AddRouter(msgId, router)
}

func (s *Server) GetConnMgr() zinterface.IConnManager {
	return s.ConnMgr
}

func (s *Server) Server() {
	// 启动server
	s.Start()
	//TODO 启动后可以做其他业务

	// 阻塞
	select {}
}

// 初始化server
func NewServer(name string) zinterface.IServer {
	server := &Server{
		Name:      name,
		IpVersion: "tcp4",
		IP:        utils.GlobalObj.Host,
		Port:      utils.GlobalObj.TcpPort,
		MsgHandle: NewMsgHandle(),
		ConnMgr:   NewConnManager(),
	}
	return server
}

// 注册hook函数
func (s *Server) SetOnConnStart(hookFunc func(connection zinterface.IConnection)) {
	s.OnConnStart = hookFunc
}

// 调用hook函数
func (s *Server) CallOnConnStart(conn zinterface.IConnection) {
	if s.OnConnStart != nil {
		logging.Info("[CallOnConnStart]")
		s.OnConnStart(conn)
	}
}

// 注册hook函数
func (s *Server) SetOnConnStop(hookFunc func(connection zinterface.IConnection)) {
	s.OnConnStop = hookFunc
}

// 调用hook函数
func (s *Server) CallOnConnStop(conn zinterface.IConnection) {
	if s.OnConnStop != nil {
		logging.Info("[CallOnConnStart]")
		s.OnConnStop(conn)
	}
}
